﻿using Kevin.Shop.Business.Core.Components;
using Kevin.Shop.Business.Products.Components;
using Kevin.Shop.Business.Service.Entity.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RiderShop.Mobile.Common.Component;
using Kevin.Shop.Business.Comments.Components;
using Kevin.Shop.Business.Service.Entity.Products.Enumerations;
using RiderShop.Mobile.ServiceEntity.Product;
using Kevin.Shop.Business.Service.Entity.SalesManagement.Shipping;
using Kevin.Shop.Business.Core.Components.Responser;
using RiderShop.Mobile.ServiceEntity.MyAccount;
using Kevin.Shop.Business.SalesManagement.Components.Order;
using Kevin.Shop.Business.Core.Member;
using Kevin.Shop.Business.SalesManagement.Components;
using System.Web;
using System.Web.Security;
using Kevin.Shop.Business.Core.Components.Cookie;
using System.Net;
using RiderShop.Mobile.Common.ThirdEntity;
using System.Xml.Serialization;
using System.IO;

namespace RiderShop.Mobile.Modle.MyAccount
{
    public static partial class MyAccountModel
    {
        /// <summary>
        /// 得到用户收货地址列表根据用户ID
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        public static List<UserShipingAddressExtend> GetShippingAddressList(int userId)
        {
            List<UserShipingAddressExtend> shippingAddressList = RestfulHelper.Query<UserShipingAddressExtend>(SiteUrl.FormatUrl("SalesManagement_GetUserShipingAddress", userId, 0));

            return shippingAddressList;
        }

        /// <summary>
        /// 得到用户收货地址根据用户Id和收货地址Id
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="shippingId">收货地址Id</param>
        /// <returns></returns>
        public static List<UserShipingAddressExtend> GetShippingAddress(int userId, int shippingId)
        {
            List<UserShipingAddressExtend> shippingAddress = RestfulHelper.Query<UserShipingAddressExtend>(SiteUrl.FormatUrl("SalesManagement_GetUserShipingAddress", userId, shippingId));

            return shippingAddress;
        }

        /// <summary>
        /// 添加用户收货地址
        /// </summary>
        /// <param name="shipingAddress">用户收货地址</param>
        /// <returns></returns>
        public static ServiceResponser AddShippingAddress(UserShipingAddress shipingAddress)
        {
            ServiceResponser result = RestfulHelper.Update<UserShipingAddress>(SiteUrl.FormatUrl("SalesManagement_CreateUserShipingAddress"), shipingAddress);

            return result;
        }

        /// <summary>
        /// 修改用户收货地址
        /// </summary>
        /// <param name="shipingAddress">用户收货地址</param>
        /// <returns></returns>
        public static ServiceResponser EditShippingAddress(UserShipingAddress shipingAddress)
        {
            ServiceResponser result = RestfulHelper.Update<UserShipingAddress>(SiteUrl.FormatUrl("SalesManagement_UpdateUserShipingAddress"), shipingAddress);

            return result;
        }

        /// <summary>
        /// 删除用户收货地址
        /// </summary>
        /// <param name="收货地址Id">收货地址Id</param>
        /// <returns></returns>
        public static ServiceResponser DeleteShippingAddress(int shippingId)
        {
            ServiceResponser result = RestfulHelper.UpdateWithQueryString(SiteUrl.FormatUrl("SalesManagement_DeleteUserShipingAddress", shippingId));


            return result;
        }

        public static ServiceResponser UpdateUser(UserBasicInfo user)
        {
            ServiceResponser result = RestfulHelper.Update<UserBasicInfo>(SiteUrl.FormatUrl("Common_CreateOrUpdateByWebSite"), user);

            return result;
        }

        /// <summary>
        /// 根据微信用户的OpenId获取相关用户信息
        /// </summary>
        /// <param name="openid"></param>
        /// <returns></returns>
        public static UserBasicInfo GetUserInfoByThirdId(string openid)
        {
            string url = SiteUrl.FormatUrl("Common_GetUserInfoByThirdId");
            var list = RestfulHelper.Query<UserBasicInfo>(SiteUrl.FormatUrl("Common_GetUserInfoByThirdId", openid));
            if (list.Count > 0)
                return list[0];
            return null;
        }

        public static CustomerModel Login(UserBasicInfo info)
        {
            var model = new CustomerModel();
            model.Login(info.UserName, info.Password);
            HttpCookie authCookie = FormsAuthentication.GetAuthCookie(info.UserName, true);
            KevinCookieManager.Set(authCookie.Name, authCookie.Value, 30);
            WebClientContext.Current.GetCurrentUser();
            return model;
        }

        /// <summary>
        /// 得到用户自提点列表
        /// </summary>
        /// <param name="userId">用户编号</param>
        /// <param name="lng">用户位置的经度</param>
        /// <param name="lat">用户位置的纬度</param>
        /// <param name="shippingId">自提点编号</param>
        /// <returns>自提点</returns>
        public static List<UserShipingAddressExtend> GetUserPickAddressList(int userId, decimal lng = 0, decimal lat = 0, int shippingId = 0)
        {
            //得到系统的所有自提点
            List<UserShipingAddressExtend> defaultPickAddressList = MyAccountModel.GetShippingAddress(100, -1) ?? new List<UserShipingAddressExtend>();

            if (shippingId > 0)
            {
                return defaultPickAddressList.Where(a => a.ShippingId == shippingId).ToList();
            }

            //1.用户没有经纬度(可能用户在公众号号里没有允许使用您的位置)
            if (lng == 0 || lat == 0)
            {
                //2.得到user的默认的收货地址
                List<UserShipingAddressExtend> userShppingAddressList = MyAccountModel.GetShippingAddressList(userId);
                var defaultUserAddress = userShppingAddressList.FirstOrDefault(a => a.IsDefault.HasValue && a.IsDefault.Value);

                //3.调用百度api得到默认的收货地址的经纬度
                if (defaultUserAddress != null && !string.IsNullOrEmpty(defaultUserAddress.Address) && !string.IsNullOrEmpty(defaultUserAddress.RegionAddress))
                {
                    string url = "http://api.map.baidu.com/geocoder/v2/?output=xml&ak=DAbdc3f5b3659bd307ccfd675e4a0730&address=" + defaultUserAddress.Address + "&city=" + defaultUserAddress.RegionAddress;
                    try
                    {
                        //log记录访问百度api拿到返回结果所需要花费的时间
                        Kevin.Comm.Logger.Tracer.TraceLog("CallBaiDuAPI:Start " + DateTime.Now, "Call BaiDu API", "CallBaiDuAPI", true);
                        string returnBody = Utility.GetBody(url, Encoding.UTF8, 3000);
                        Kevin.Comm.Logger.Tracer.TraceLog("CallBaiDuAPI:End " + DateTime.Now, "Call BaiDu API", "CallBaiDuAPI", true);

                        using (StringReader sr = new StringReader(returnBody))
                        {
                            XmlSerializer xs = new XmlSerializer(typeof(GeocoderSearchResponse));
                            GeocoderSearchResponse baiduMap = xs.Deserialize(sr) as GeocoderSearchResponse;

                            if (baiduMap != null && baiduMap.status == 0)
                            {
                                lng = baiduMap.result.location.lng;
                                lat = baiduMap.result.location.lat;
                            }
                            else
                            {
                                lng = 0M;
                                lat = 0M;
                            }
                        }
                    }
                    catch
                    {
                        lng = 0M;
                        lat = 0M;
                    }
                }
            }
            //4.取到用户的经纬度或者默认收货地址的经纬度
            if (lng != 0 && lat != 0)
            {
                if (defaultPickAddressList != null && defaultPickAddressList.Count > 0)
                {
                    //5.计算用户的经纬度或者默认收货地址的经纬度到每个自提点的距离
                    foreach (var defaultPickAddress in defaultPickAddressList)
                    {
                        if (defaultPickAddress.Longitude.HasValue && defaultPickAddress.Latitude.HasValue)
                        {
                            //以前的算记录方式
                            //decimal distance = GetDistance(lng, lat, defaultPickAddress.Longitude.Value, defaultPickAddress.Latitude.Value);
                            //defaultPickAddress.Distance = distance;

                            double distance = GetDistance((double)lng, (double)lat, (double)defaultPickAddress.Longitude.Value, (double)defaultPickAddress.Latitude.Value);
                            defaultPickAddress.Distance = decimal.Parse(distance.ToString("N2"));
                        }
                    }
                }
                //按距离升序排列(第一个是距离最近的)
                defaultPickAddressList = defaultPickAddressList.OrderBy(userPickAddress => userPickAddress.Distance).ToList();
            }
            else//6.取不到默认收货地址的经纬度（收货地址填写的内容，调用百度API有可能拿不到经纬度）或者user没有默认收货地址
            {
                //得到user的默认的收货地址
                List<UserShipingAddressExtend> userShppingAddressList = MyAccountModel.GetShippingAddressList(userId);
                var defaultUserAddress = userShppingAddressList.FirstOrDefault(a => a.IsDefault.HasValue && a.IsDefault.Value);

                if (defaultUserAddress != null && defaultUserAddress.RegionId > 0)
                {
                    defaultPickAddressList = defaultPickAddressList.OrderBy(userPickAddress => Math.Abs(userPickAddress.RegionId - defaultUserAddress.RegionId)).ToList();
                }
            }

            //得到用户的自提点
            List<UserShipingAddressExtend> suggestPickAddressList = null;
            //如果用户有自己的自提点，那么把用户的自提点提前
            if (!string.IsNullOrEmpty(WebClientContext.Current.CurrentUser.PickUpAddress))
            {
                suggestPickAddressList = new List<UserShipingAddressExtend>();
                var userPickAddressList = WebClientContext.Current.CurrentUser.PickUpAddress.Split(',');

                if (userPickAddressList != null && userPickAddressList.Length > 0)
                {
                    foreach (var userPickUpId in userPickAddressList)
                    {
                        var userPickUp = defaultPickAddressList.FirstOrDefault(a => userPickUpId == a.ShippingId.ToString());
                        if (userPickUp != null)
                        {
                            //添加默认地址
                            suggestPickAddressList.Add(userPickUp);
                            //从default删除
                            defaultPickAddressList.Remove(userPickUp);
                        }
                    }
                }
                //添加其余地址
                suggestPickAddressList.AddRange(defaultPickAddressList);
            }
            else
            {
                suggestPickAddressList = defaultPickAddressList;
            }

            return suggestPickAddressList;
        }

        /// <summary>
        /// 得到默认收货地址到自提点的距离
        /// </summary>
        /// <param name="lng">经度(用户的经度 | 默认收货地址的经度)</param>
        /// <param name="lat">纬度(用户的纬度 | 默认收货地址的纬度)</param>
        /// <param name="pickAddressLng">自提点的经度</param>
        /// <param name="pickAddressLat">自提点的纬度</param>
        /// <returns>距离 单位米</returns>
        public static decimal GetDistance(decimal lng, decimal lat, decimal pickAddressLng, decimal pickAddressLat)
        {
            var jl_jd = 102834.74258026089786013677476285M;//每经度单位米;
            var jl_wd = 111712.69150641055729984301412873M;//每纬度单位米;
            var b = Math.Abs((lng - pickAddressLng) * jl_jd);
            var a = Math.Abs((lat - pickAddressLat) * jl_wd);
            var distance = Math.Sqrt((double)(a * a + b * b));

            return (decimal)distance;
        }


        public static double GetDistance(double lng, double lat, double pickAddressLng, double pickAddressLat)
        {
           double EARTH_RADIUS = 6378.137;//地球的半径
           double radLat1 = rad(lat);   
           double radLat2 = rad(pickAddressLat);  
           double a = radLat1 - radLat2;  
           double b = rad(lng) - rad(pickAddressLng);
           double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + (Math.Cos(radLat1)) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
           if (double.IsNaN(s))
           {
               s = 0.0;
           }
            
            
           s = s * EARTH_RADIUS;
           s = Math.Round(s * 10000) / 10000;
           s = s*1000;

           return Math.Ceiling(s);  
        }

        public static double rad(double d)  
        {  
          return d * 3.1415926535898 / 180.0;  
        } 
    }
}
